package com.jevons.muffin.adapter;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * 图片懒加载
 * @author linaisheng
 * Created at 2019/3/28.
 */

public abstract class LazyImageAdapter<T> extends BaseAdapter<T>{

    //加载中的图片
    private Bitmap mLoadingBitmap;
    //加载错误的图片
    private Bitmap mErrorBitmap;

    /**
     * 图片缓存技术的核心类，用于缓存所有下载好的图片
     * 在程序内存达到设定值时会将最少最近使用的图片移除掉
     */
    private LruCache<String, BitmapDrawable> mMemoryCache;

    public LazyImageAdapter(Context context, List list) {
        this(context, null, list);
    }

    public LazyImageAdapter(Context context, Bitmap loadingBitmap, List list) {
       this(context, loadingBitmap, null, list);
    }

    public LazyImageAdapter(Context context, Bitmap loadingBitmap, Bitmap errorBitmap, List list) {
        super(context, list);
        mLoadingBitmap = loadingBitmap;
        mErrorBitmap = errorBitmap;
        //获取获取应用程序最大可用内存
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 12;
        mMemoryCache = new LruCache<String, BitmapDrawable>(cacheSize) {
            @Override
            protected int sizeOf(String key, BitmapDrawable value) {
                return value.getBitmap().getByteCount();
            }
        };
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view;
        if (convertView == null) {
            view = inflate(getLayoutId());
        } else {
            view = convertView;
        }

        String url = getImageUrl(position);

        ImageView imageView = (ImageView) view.findViewById(getImageViewId());
        BitmapDrawable drawable = getBitmapFormMemoryCache(url);
        if (drawable != null) {
            imageView.setImageDrawable(drawable);
        } else if (cancelPotentialWork(url, imageView)) {
            BitmapWorkerTask task = new BitmapWorkerTask(position, imageView);
            AsyncDrawable asyncDrawable = new AsyncDrawable(getContext().getResources(),
                    mLoadingBitmap, task);
            imageView.setImageDrawable(asyncDrawable);
            task.execute(url);
        }
        initView(view, position);
        return view;
    }

    /**
     * 将一张图片存储到Cache中
     * @param key
     * @param drawable
     */
    public void addBitmapToMemoryCache(String key, BitmapDrawable drawable) {
        if (getBitmapFormMemoryCache(key) == null) {
            mMemoryCache.put(key, drawable);
        }
    }

    /**
     * 从Cache中获取一张图片
     * @param key
     * @return
     */
    public BitmapDrawable getBitmapFormMemoryCache(String key) {
        return mMemoryCache.get(key);
    }


    protected abstract int getLayoutId();

    protected abstract int getImageViewId();

    protected abstract void initView(View view, int position);

    protected abstract String getImageUrl(int position);

    protected void setErrorBitmap(Bitmap errorBitmap){
        this.mErrorBitmap = errorBitmap;
    }
    /**
     * 获取传入的ImageView它所对应的BitmapWorkerTask
     * @param imageView
     * @return
     */
    private BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
        if (imageView != null) {
            Drawable drawable = imageView.getDrawable();
            if (!(drawable instanceof LazyImageAdapter.AsyncDrawable)) {
                return null;
            } else {
                AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                return asyncDrawable.getBitmapWorkerTask();
            }
        }
        return null;
    }

    public boolean cancelPotentialWork(String url, ImageView imageView) {
        BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
        if (bitmapWorkerTask != null) {
            String imageUrl = bitmapWorkerTask.imageUrl;
            if (imageUrl == null || !imageUrl.equals(url)) {
                bitmapWorkerTask.cancel(true);
            } else {
                return false;
            }
        }
        return true;
    }

    private class AsyncDrawable extends BitmapDrawable {

        private WeakReference<BitmapWorkerTask> bitmapWorkerTaskWeakReference;

        public AsyncDrawable(Resources res, Bitmap bitmap,
                             BitmapWorkerTask bitmapWorkerTask) {
            super(res, bitmap);
            bitmapWorkerTaskWeakReference =
                    new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
        }

        /**
         * 从Drawable中获取任务
         * @return
         */
        public BitmapWorkerTask getBitmapWorkerTask() {
            return bitmapWorkerTaskWeakReference.get();
        }
    }

    //图片下载任务
    private class BitmapWorkerTask extends AsyncTask<String, Void, BitmapDrawable> {

        int position;
        String imageUrl;

        private WeakReference<ImageView> imageViewWeakReference;

        public BitmapWorkerTask(int position, ImageView imageView) {
            this.position = position;
            imageViewWeakReference = new WeakReference<ImageView>(imageView);
        }


        @Override
        protected BitmapDrawable doInBackground(String... params) {
            imageUrl = params[0];
            //在后台开始下载图片
            Bitmap bitmap = downloadBitmap(imageUrl);
            if (bitmap != null) {
                BitmapDrawable drawable = new BitmapDrawable(bitmap);
                addBitmapToMemoryCache(imageUrl, drawable);
                return drawable;
            } else {
                return null;
            }
        }

        @Override
        protected void onPostExecute(BitmapDrawable drawable) {
            ImageView imageView = getAttachedImageView();
            if (imageView != null) {
                if (drawable != null) {
                    imageView.setImageDrawable(drawable);
                } else {
                    imageView.setImageDrawable(new BitmapDrawable(mErrorBitmap));
                }
            }
        }

        private ImageView getAttachedImageView() {
            ImageView imageView = imageViewWeakReference.get();
            BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
            if (this == bitmapWorkerTask) {
                return imageView;
            }
            return null;
        }

        //图片下载
        private Bitmap downloadBitmap(String imageUrl) {
            Bitmap bitmap = null;
            HttpURLConnection con = null;
            try {
                URL url = new URL(imageUrl);
                con = (HttpURLConnection) url.openConnection();
                con.setConnectTimeout( 5 * 1000);
                con.setReadTimeout(10 * 1000);
                bitmap = BitmapFactory.decodeStream(con.getInputStream());
            } catch (Exception e) {

            } finally {
                if (con != null) {
                    con.disconnect();
                }
            }
            return bitmap;
        }

    }

}
